#pragma once

#include "i_io.h"
#include "BaseIocpInitiator.h"

namespace wxtl
{
	class File;
	class _win32_error;
}

struct IocpOperation;

struct IocpIoRequest
{
	enum Type
	{
		None = 0, Read, Write, TransmitFile, _BaseRequestEnd
	} ;

	IocpIoRequest()
		:m_type(None)
	{

	}

	IocpIoRequest(IocpOperation* operation, Type type, void* data, size_t size)
		:m_type(type)
		,m_data(data)
		,m_dataSize(size)
		,m_operation(operation)
	{

	}

	IocpIoRequest(IocpOperation* operation, wxtl::File* file, size_t byteToWrite, Buffer* head = NULL, Buffer* tail = NULL)
		:m_type(TransmitFile)
		,m_dataSize(byteToWrite)
		,m_file(file)
		,m_head(head)
		,m_tail(tail)
		,m_operation(operation)
	{

	}
	Type m_type;
	void* m_data;
	size_t m_dataSize;
	wxtl::File* m_file;
	Buffer* m_head;
	Buffer* m_tail;
	IocpOperation* m_operation;
};

class IocpIoBaseInitiator :	public BaseIocpInitiator
{
public:
	IocpIoBaseInitiator(void);
	virtual ~IocpIoBaseInitiator(void);

	//I_Io
	//these io calls are marshaled to be called outside of fiber context
	//because iocp operations could proceed before execution is switched back from from fiber context,
	//so it would try to switch to fiber, that already in execution
	virtual size_t Read(void* data, size_t size);
	virtual size_t Write(void* data, size_t size);
	virtual void TransmitFile(wxtl::File* file, size_t bytesToWrite, Buffer* head, Buffer* tail);

	bool IocpCopy(IocpIoBaseInitiator* to, size_t length , size_t portion = 16192);

	virtual void OnSwithcedContext();

protected:
	IocpIoRequest m_request;


};

